﻿#region Includes

using System.Net;
using System.Net.Sockets;
using System.Threading;
using NLog;
using Thought.Net.Telnet;
using ArtheaEngine.Model;
using ArtheaEngine;

#endregion

namespace ArtheaServer
{
    public class Server
    {
        private static readonly Logger Log = LogManager.GetCurrentClassLogger();
        private TelnetListener _listener;
        private Thread _listenThread;

        public Server(World world)
        {
            World = world;
        }

        public void Listen()
        {
            State = ServerState.Initializing;

            _listener = new TelnetListener(IPAddress.Any, World.Port);

            _listener.Start();

            Log.Info(World.Name + " accepting connections on port " + World.Port);

            UpdateManager.AddWorld(World);

            State = ServerState.Running;

            while (State == ServerState.Running)
            {
                try
                {
                    var client = _listener.Accept();

                    var connection = new Connection(client, this);

                    Log.Info("Got " + client.Parser.Socket.RemoteEndPoint);

                    new Thread(connection.Run) {IsBackground = true}.Start();
                }
                catch (SocketException)
                {
                }
            }
        }

        public void Start()
        {
            _listenThread = new Thread(Listen) {Name = World.Name};
            _listenThread.Start();
        }

        public void Stop()
        {
            Log.Info("Stopping server...");

            State = ServerState.Stopped;

            if (_listener != null)
            {
                _listener.Stop();
                _listener = null;
            }

            Thread.Sleep(500);

            if (_listenThread != null && _listenThread.IsAlive)
            {
                _listenThread.Abort();
            }
        }

        public ServerState State { get; set; }
        public World World { get; set; }
    }

    public enum ServerState
    {
        Initializing,
        Running,
        Stopped
    }
}